package com.zijidelu.luframework.infrastructure.model.api;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.zijidelu.luframework.base.model.BaseModel;

import java.util.List;
import java.util.function.Function;

/**
 * 分页响应模型。
 *
 * @author ZIJIDELU
 * @datetime 2025/10/20 14:01
 */
public class PageResponse<T extends BaseModel> implements IPage<T> {
    @JsonIgnore
    private final IPage<T> page;

    private final List<T> records;
    private final long total;
    private final long size;
    private final long current;
    private final long pages;

    @Override
    public List<T> getRecords() {
        return records;
    }

    @Override
    public long getTotal() {
        return total;
    }

    @Override
    public long getSize() {
        return size;
    }

    @Override
    public long getCurrent() {
        return current;
    }

    @Override
    public long getPages() {
        return pages;
    }

    private PageResponse(IPage<T> iPage) {
        this.page = iPage;
        this.records = iPage.getRecords();
        this.total = iPage.getTotal();
        this.size = iPage.getSize();
        this.current = iPage.getCurrent();
        this.pages = iPage.getPages();
    }

    /**
     * 创建分页响应模型。
     *
     * @param iPage 分页接口
     * @param <T>   记录类型
     * @return 分页响应模型
     */
    public static <T extends BaseModel> PageResponse<T> of(IPage<T> iPage) {
        return new PageResponse<>(iPage);
    }

    /**
     * 转换记录。
     *
     * @param mapper 记录映射函数
     * @param <R>    转换后的记录类型
     * @return 转换后的分页响应模型
     */
    public <R extends BaseModel> PageResponse<R> convertRecords(Function<? super T, ? extends R> mapper) {
        return of(page.convert(mapper));
    }

    @Override
    public List<OrderItem> orders() {
        return page.orders();
    }

    @Override
    public IPage<T> setRecords(List<T> records) {
        throw new UnsupportedOperationException("PageResponse is immutable");
    }

    @Override
    public IPage<T> setTotal(long total) {
        throw new UnsupportedOperationException("PageResponse is immutable");
    }

    @Override
    public IPage<T> setSize(long size) {
        throw new UnsupportedOperationException("PageResponse is immutable");
    }

    @Override
    public IPage<T> setCurrent(long current) {
        throw new UnsupportedOperationException("PageResponse is immutable");
    }
}
